#include "netPack.h"
#include "PackDefine.h"

//PackInfo
PackInfo::PackInfo()
{
	DeviceID = 0;
	SubDevID = 0;
	Length = 0;
	CmdID = -1;
	Result = 0;
}

bool PackInfo::IsRecvPack() const
{
	Q_ASSERT(CmdID != -1);
	if (CmdID == BTS_CMD_CONNECT_RESP
		|| CmdID == BTS_CMD_SEND_INFO_RESP
		|| CmdID == BTS_CMD_GET_RTC_RESP
		|| CmdID == BTS_CMD_SET_RTC_RESP
		|| CmdID == BGS66_CMD_SET_RT_INTERVAL_RESP
		|| CmdID == BTS_CMD_SEND_PARALLEL_RESP
		|| CmdID == BTS70_CMD_SET_TESTID_RESP
		|| CmdID == BTS_CMD_SET_BGSAUX_MAP_RESP70
		|| CmdID == BTS_CMD_SET_BGSAUX_RESP
		|| CmdID == BTS_CMD_SET_STEP_EX_RESP76
		|| CmdID == BTS_CMD_START_RESP70
		|| CmdID == BTS_CMD_STOP_RESP
		|| CmdID == BTS_CMD_SEND_LOG_RESP
		|| CmdID == BTS_CMD_SEND_DFDATA_RESP76)
		return true;

	return false;
}

int PackInfo::headLength() const
{
	return IsRecvPack() ? 7 : 6;
}

int PackInfo::bodyLength() const
{
	return Length - 8 - 2 - headLength();
}

bool PackInfo::Pack(QByteArray &buffer) const
{
	QDataStream out(&buffer, QIODevice::WriteOnly);
	out.setByteOrder(QDataStream::LittleEndian);

	out << DeviceID;
	out << SubDevID;
	out << Length;
	out << CmdID;
	if (IsRecvPack())
		out << Result;

	return true;
}

bool PackInfo::UnPack(QByteArray &buffer,int offset)
{	
	int pack_len = 6;	
	int head_len = 8;
	int tail_len = 2;
	if (offset + pack_len + tail_len > buffer.size())
		return false;

	uchar *ptr = (uchar *)buffer.data();

	DeviceID = (uchar)buffer[offset];
	SubDevID = (uchar)buffer[offset + 1];
	Length = *((ushort*)(ptr + offset + 2));
	CmdID = *((ushort*)(ptr + offset + 4));

	if (IsRecvPack())
	{
		Result = (uchar)buffer[offset + 6];
		pack_len += 1;
	}
	int body_len = Length - pack_len - head_len - tail_len;
	if (offset + pack_len + body_len + tail_len > buffer.size())
		return false;

	return true;
}

//
NetPack::NetPack()	
{		
	
}

NetPack::~NetPack()
{
}


//NetPackManager
NetPackManager::NetPackManager()
{
	mPackSeq = 1;
}

NetPackManager *NetPackManager::instance()
{
	static NetPackManager inst;
	return &inst;
}

int NetPackManager::genSeq()
{
	return mPackSeq++;
}

NetPack *NetPackManager::createPack(int id)
{
	if (mPackFactory.contains(id))
		return mPackFactory[id]();

	Q_ASSERT(0);
	return NULL;
}